package com.sgcc.epri.dcloud.util;

import com.alibaba.druid.util.StringUtils;
import com.sgcc.epri.dcloud.pojo.*;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class ChoreUtil {

    private static final Logger log =  LoggerFactory.getLogger(ChoreUtil.class);

    /**
     * List<Map> to </Map>
     * @param list
     * @return
     */
    public static Map<String, Object> getTableNameMap(List<Map<String, Object>> list){
        // 转换为Map
        Map<String, Object> map = new HashMap<String, Object>();
        for (Map<String, Object> som : list) {
            map.put(som.get("code")+"", som.get("name"));
        }

//        String nr = "电网、发电厂、发电机、变压器绕组、交流线端、直流输电系统";

//        String[] split = nr.split("、");
//        for (int i = 0; i < split.length; i++) {
//            map.put(i+1+"", split[i]);
//        }
        return map;
    }

    /**
     * List<Map> to </Map>
     * @param list
     * @return
     */
    public static Map<String, Object> getTableNameMapRe(List<Map<String, Object>> list){
        // 转换为Map
        Map<String, Object> map = new HashMap<String, Object>();
        for (Map<String, Object> som : list) {
            map.put(som.get("name")+"", som.get("code"));
        }
        return map;
    }

    /**
     * List<Map> to </Map>
     * @param list
     * @return
     */
    public static Map<String, TableHead> getTableNameMapObjH(List<TableHead> list){
        // 转换为Map
        return list.stream().collect(Collectors.toMap(
                TableHead::getObjectId,
                map -> map
        ));
    }

    /**
     * List<Map> to </Map>
     * @param list
     * @return
     */
    public static Map<String, CalResultAll> getTableNameMapObjD(List<CalResultAll> list, List<DataMaintenance> dmm){
        Map<String, String> codeOrc = new HashMap<>();
        for (DataMaintenance dataMaintenance : dmm) {
            codeOrc.put(dataMaintenance.getNrCode(), dataMaintenance.getDkyCode());
        }

        // 转换为Map
        Map<String, CalResultAll> map = new HashMap<String, CalResultAll>();
        for (CalResultAll c : list) {
            String s = codeOrc.get(c.getObjectId());
            if(null == s) continue;
            map.put(s+c.getDatasource()+c.getParentIdIndex(), c);
        }
        return map;
    }

    /**
     * List<Map> to </Map>
     * @param list
     * @return
     */
    public static Map<String, DataMaintenance> getTableNameMapOrc(List<DataMaintenance> list){
        // 转换为Map
        Map<String, DataMaintenance> map = new HashMap<String, DataMaintenance>();
        for (DataMaintenance dataMaintenance : list) {
            map.put(dataMaintenance.getDkyCode(), dataMaintenance);
        }
        return map;
    }

    /**
     * 分割rowkey
     * @param rowkey
     * @return
     */
    public static Map<String, Object> getParamByStr(String rowkey){
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("datasource", rowkey.substring(0, 10));
        paramMap.put("assetId", rowkey.substring(10, 20));
        paramMap.put("date", rowkey.substring(rowkey.length() - 8));
        if (rowkey.length() == 46) {
            paramMap.put("devId", rowkey.substring(20, 38));
        } else if (rowkey.length() == 42) {
            paramMap.put("devId", rowkey.substring(20, 34));
        } else if (rowkey.length() == 38) {
            paramMap.put("devId", rowkey.substring(20, 30));
        }
        return paramMap;
    }

    /**
     * a时间是否在b时间之前
     * @param stopTime
     * @param currentDate
     * @return
     */
    public static boolean dateIsBefore(String stopTime, String currentDate){
        if (isAlpha(stopTime)) {
            return true;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date1 = LocalDate.parse(stopTime, formatter);
        LocalDate date2 = LocalDate.parse(currentDate, formatter);
        return date1.isBefore(date2);
    }

    public static List<AssetTypeParamCenter> strToArray(String id){
        List<AssetTypeParamCenter> params = new ArrayList<>();
        AssetTypeParamCenter assetTypeParamCenter = new AssetTypeParamCenter();
        assetTypeParamCenter.setAssetId(id);
        params.add(assetTypeParamCenter);
        return params;
    }

     public static final BigDecimal oneHundred = new BigDecimal("100");
     public static final BigDecimal one = new BigDecimal("1");

    /**
     * 数据合并
     * @param a
     * @param b
     * @return
     */
    public static List<Map<String, Object>> mergeDataIntegrality(List<Map<String, Object>> a, List<Map<String, Object>> b){

        List<Map<String, Object>> max = null;
        List<Map<String, Object>> min = null;

        if (a.size() >= b.size()) {
            max = a;
            min = b;
        }else{
            max = b;
            min = a;
        }

        Map<String, Map<String, Object>> minMap = new HashMap<>();
        min.forEach(m -> minMap.put(m.get("id")+"", m));

        for (Map<String, Object> mapMax : max) {
            Object id = mapMax.get("id");

            Map<String, Object> mapOneMin = minMap.get(id);
            if (mapOneMin == null) {
                continue;
            }

            BigDecimal assetNumMax = new BigDecimal(mapMax.get("asset_num") + "");// 资产数量
            BigDecimal actualAssetNumMax = new BigDecimal(mapMax.get("actual_asset_num") + "");// 应上送资产数量
            BigDecimal actualDaysNumMax = new BigDecimal(mapMax.get("actual_days_num") + "");// 数据完整天数
            BigDecimal daysNumMax = new BigDecimal(mapMax.get("days_num") + "");// 规划数据天数

            BigDecimal assetNumMin = new BigDecimal(mapOneMin.get("asset_num") + "");// 资产数量
            BigDecimal actualAssetNumMin = new BigDecimal(mapOneMin.get("actual_asset_num") + "");// 应上送资产数量
            BigDecimal actualDaysNumMin = new BigDecimal(mapOneMin.get("actual_days_num") + "");// 数据完整天数
            BigDecimal daysNumMin = new BigDecimal(mapOneMin.get("days_num") + "");// 规划数据天数

            BigDecimal assetNum = assetNumMax.add(assetNumMin);
            BigDecimal actualAssetNum = actualAssetNumMax.add(actualAssetNumMin);
            BigDecimal actualDaysNum = actualDaysNumMax.add(actualDaysNumMin);
            BigDecimal daysNum = daysNumMax.add(daysNumMin);

            BigDecimal accessRate = actualAssetNum.divide(assetNum, 4, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(2, BigDecimal.ROUND_DOWN);
            BigDecimal daysRate = actualDaysNum.divide(daysNum, 4, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(2, BigDecimal.ROUND_DOWN);

            mapMax.put("asset_num", assetNum);
            mapMax.put("actual_asset_num", actualAssetNum);
            mapMax.put("actual_days_num", actualDaysNum);
            mapMax.put("days_num", daysNum);
            mapMax.put("access_rate", accessRate.toString().equals("100.00")?"100":accessRate);
            mapMax.put("days_rate", daysRate.toString().equals("100.00")?"100":daysRate);

        }
        return max;
    }

    /**
     * 数据合并
     * @param a
     * @param b
     * @return
     */
    public static List<Map<String, Object>> mergeDataaccuracyRate(List<Map<String, Object>> a, List<Map<String, Object>> b){

        List<Map<String, Object>> max = null;
        List<Map<String, Object>> min = null;

        if (a.size() >= b.size()) {
            max = a;
            min = b;
        }else{
            max = b;
            min = a;
        }

        Map<String, Map<String, Object>> minMap = new HashMap<>();
        min.forEach(m -> minMap.put(m.get("datasource")+"", m));

        for (Map<String, Object> mapMax : max) {
            Object datasource = mapMax.get("datasource");

            Map<String, Object> mapOneMin = minMap.get(datasource);
            if (mapOneMin == null) {
                continue;
            }

            BigDecimal fenziMax = new BigDecimal(mapMax.get("fenzi") + "");
            BigDecimal fenmuMax = new BigDecimal(mapMax.get("fenmu") + "");

            BigDecimal fenziMin = new BigDecimal(mapOneMin.get("fenzi") + "");
            BigDecimal fenmuMin = new BigDecimal(mapOneMin.get("fenmu") + "");

            BigDecimal fenzi = fenziMax.add(fenziMin);
            BigDecimal fenmu = fenmuMax.add(fenmuMin);

            BigDecimal accessRate = fenzi.divide(fenmu, 4, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(2, BigDecimal.ROUND_DOWN);

            mapMax.put("fenzi", fenzi);
            mapMax.put("fenmu", fenmu);
            mapMax.put("value", accessRate.toString().equals("100.00")?"100":accessRate);

        }
        return max;
    }

    /**
     * 数据合并
     * @param a
     * @param b
     * @return
     */
    public static List<CalResultAll> mergeDataaccuracyRateAllDay(List<CalResultAll> a, List<CalResultAll> b){

        if (a == null) {
            a = b;
            return a;
        }

        Map<String, CalResultAll> datasourceOrc = new HashMap<>();
        for (CalResultAll calResultAll : b) {
            datasourceOrc.put(calResultAll.getDatasource(),calResultAll);
        }

        for (CalResultAll calResultAll : a) {
            CalResultAll orc = datasourceOrc.get(calResultAll.getDatasource());
            if(orc == null) continue;

            BigDecimal cm = new BigDecimal(calResultAll.getMolecule());
            BigDecimal cd = new BigDecimal(calResultAll.getDenominator());
            BigDecimal om = new BigDecimal(orc.getMolecule());
            BigDecimal od = new BigDecimal(orc.getDenominator());

            BigDecimal fzAdd = cm.add(om);
            BigDecimal fmAdd = cd.add(od);

            BigDecimal cR = cm.divide(cd, 4, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(2, BigDecimal.ROUND_DOWN);
            BigDecimal oR = om.divide(od, 4, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(2, BigDecimal.ROUND_DOWN);

            BigDecimal oAdd = cR.add(oR);

            calResultAll.setMolecule(fzAdd.toString());
            calResultAll.setDenominator(fmAdd.toString());
            calResultAll.setValue(oAdd.toString());


            if(calResultAll.getOverallRatio() == null) {
                BigDecimal divide = cm.divide(cd, 4, BigDecimal.ROUND_DOWN);
                BigDecimal value = ChoreUtil.one.subtract(divide).multiply(ChoreUtil.oneHundred).setScale(2, BigDecimal.ROUND_DOWN);
                calResultAll.setOverallRatio(value);
            }
            BigDecimal divide = om.divide(od, 4, BigDecimal.ROUND_DOWN);
            BigDecimal value = ChoreUtil.one.subtract(divide).multiply(ChoreUtil.oneHundred).setScale(2, BigDecimal.ROUND_DOWN);
            BigDecimal add = calResultAll.getOverallRatio().add(value);
            calResultAll.setOverallRatio(add);

        }

        return a;
    }


    /**
     * 数据校验
     * @return
     */
    public static boolean checkParam(TreeNode treeNode, TableHead tableHead, List<ManagementUnit> managementUnits,List<AssetTypeParamCenter> param){
        // 校验 ------------------------------------------------------------------------
        if(managementUnits.size() == 0){
            log.info("此次任务缺少数据源参数！树形结构：{}，表头：{}",treeNode,tableHead);
            return true;
        }
        if(param.size() == 0){
            log.info("此次任务缺少资产范围参数！树形结构：{}，表头：{}, param:{}",treeNode,tableHead, param);
            return true;
        }
        return false;
    }


    public static boolean isAlpha(CharSequence cs) {
        return cs == null || cs.length() == 0;
    }

    public final static Map<String, Map<String, Object>> conditionMap = new HashMap();
    {
        // 数据类型条件------------------------------------------------------
        Map<String, Object> dataType = new HashMap();
        dataType.put("nameChn", "数据类型");
        dataType.put("nameEng", "dataType");
        List<Map<String, Object>> dataTypeChild = new ArrayList<>();
        Map<String, Object> dtc1 = new HashMap<>();
        dtc1.put("code", "0");
        dtc1.put("name", "电量");
        dataTypeChild.add(dtc1);
        Map<String, Object> dtc2 = new HashMap<>();
        dtc2.put("code", "1");
        dtc2.put("name", "非电量");
        dataTypeChild.add(dtc2);
        dataType.put("child", dataTypeChild);
        conditionMap.put("dataType", dataType);
        //统计类型条件------------------------------------------------------
        Map<String, Object> statisticsType = new HashMap<>();
        statisticsType.put("nameChn", "统计类型");
        statisticsType.put("nameEng", "statisticsType");
        List<Map<String, Object>> statisticsTypeChild = new ArrayList<>();
        Map<String, Object> stc1 = new HashMap<>();
        stc1.put("code", "0");
        stc1.put("name", "单天");
        statisticsTypeChild.add(stc1);
        Map<String, Object> stc2 = new HashMap<>();
        stc2.put("code", "1");
        stc2.put("name", "总数");
        statisticsTypeChild.add(stc2);
        statisticsType.put("child", statisticsTypeChild);
        conditionMap.put("statisticsType", statisticsType);
    }

    public static final TreeNode treeNode = new TreeNode();
    {
        treeNode.setId(001l);
        treeNode.setLevel("1");
        treeNode.setParentId("0");
        treeNode.setFileType("datasource");
        treeNode.setTitle("数据源");
    }

    public static String toPinyin(String chinese) {
        StringBuilder pinyin = new StringBuilder();
        for (char c : chinese.toCharArray()) {
            if (Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
                // 如果是中文字符，则转换为拼音
                String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c);
                if (pinyinArray != null) {
                    pinyin.append(pinyinArray[0]); // 这里简单处理，只取了一个音，实际情况可能更复杂
                }
            } else {
                // 如果不是中文字符，则直接添加
                pinyin.append(c);
            }
        }
        return pinyin.toString();
    }

    public static final Map<String,List<Map<String, Object>>> dynamicHeader = new HashMap<>();
    {
        List<Map<String, Object>> integralityOneList = new ArrayList<>();
        Map<String, Object> map1 = new HashMap();
        map1.put("name_chn", "资产类型");
        map1.put("name_eng", "asset_name");
        Map<String, Object> map2 = new HashMap<>();
        map2.put("name_chn", "上送密度");
        map2.put("name_eng", "updensity_name");
        Map<String, Object> map3 = new HashMap<>();
        map3.put("name_chn", "资产编码");
        map3.put("name_eng", "asset_id");
        Map<String, Object> map4 = new HashMap<>();
        map4.put("name_chn", "接入率(%)");
        map4.put("name_eng", "value_1001");
        map4.put("index_id", "1001");
        Map<String, Object> map5 = new HashMap<>();
        map5.put("name_chn", "数据完整天数比率(%)");
        map5.put("name_eng", "value_1002");
        map5.put("index_id", "1002");
        Map<String, Object> map6 = new HashMap<>();
        map6.put("name_chn", "资产数");
        map6.put("name_eng", "value_1004");
        map6.put("index_id", "1004");

        integralityOneList.add(map1);
        integralityOneList.add(map2);
        integralityOneList.add(map3);
        integralityOneList.add(map4);
        integralityOneList.add(map5);
        integralityOneList.add(map6);
        dynamicHeader.put("integralityOneList", integralityOneList);

        List<Map<String, Object>> integralityTwoList1001 = new ArrayList<>();
        List<Map<String, Object>> integralityTwoList1002 = new ArrayList<>();
        List<Map<String, Object>> integralityTwoList1004 = new ArrayList<>();
        Map<String, Object> map7 = new HashMap<>();
        map7.put("name_chn", "数据源");
        map7.put("name_eng", "datasourceName");
        Map<String, Object> map8 = new HashMap<>();
        map8.put("name_chn", "对象ID");
        map8.put("name_eng", "devId");
        Map<String, Object> map9 = new HashMap<>();
        map9.put("name_chn", "考核起始时间");
        map9.put("name_eng", "examinationTime");
        Map<String, Object> map10 = new HashMap<>();
        map10.put("name_chn", "数据最早时间");
        map10.put("name_eng", "beforeTime");

        Map<String, Object> map11 = new HashMap<>();
        map11.put("name_chn", "接入率(%)");
        map11.put("name_eng", "value");
        Map<String, Object> map12 = new HashMap<>();
        map12.put("name_chn", "数据完整天数比率(%)");
        map12.put("name_eng", "value");
        Map<String, Object> map13 = new HashMap<>();
        map13.put("name_chn", "资产数");
        map13.put("name_eng", "value");

        integralityTwoList1001.add(map7);
        integralityTwoList1001.add(map8);
        integralityTwoList1001.add(map9);
        integralityTwoList1001.add(map10);
        integralityTwoList1001.add(map11);

        integralityTwoList1002.add(map7);
        integralityTwoList1002.add(map8);
        integralityTwoList1002.add(map9);
        integralityTwoList1002.add(map10);
        integralityTwoList1002.add(map12);

        integralityTwoList1004.add(map7);
        integralityTwoList1004.add(map8);
        integralityTwoList1004.add(map9);
        integralityTwoList1004.add(map10);
        integralityTwoList1004.add(map13);

        dynamicHeader.put("integralityOneList1001", integralityTwoList1001);
        dynamicHeader.put("integralityOneList1002", integralityTwoList1002);
        dynamicHeader.put("integralityOneList1004", integralityTwoList1004);

        List<Map<String, Object>> accuracyRateContent = new ArrayList<>();
        Map<String, Object> map14 = new HashMap<>();
        map14.put("name_chn", "资产类型");
        map14.put("name_eng", "assetName");
        Map<String, Object> map15= new HashMap<>();
        map15.put("name_chn", "量测编码");
        map15.put("name_eng", "assetId");
        Map<String, Object> map16 = new HashMap<>();
        map16.put("name_chn", "资产数");
        map16.put("name_eng", "denominator");
        Map<String, Object> map17 = new HashMap<>();
        map17.put("name_chn", "问题资产数");
        map17.put("name_eng", "molecule");
        Map<String, Object> map18 = new HashMap<>();
        map18.put("name_chn", "关联规则数");
        map18.put("name_eng", "relevanceRuleNum");
        Map<String, Object> map19 = new HashMap<>();
        map19.put("name_chn", "准确率(%)");
        map19.put("name_eng", "value");
        accuracyRateContent.add(map14);
        accuracyRateContent.add(map15);
        accuracyRateContent.add(map16);
        accuracyRateContent.add(map17);
        accuracyRateContent.add(map18);
        accuracyRateContent.add(map19);
        dynamicHeader.put("accuracyRateContent1003", accuracyRateContent);

        List<Map<String, Object>> accuracyRateContentTwoLevel = new ArrayList<>();
        Map<String, Object> map20 = new HashMap<>();
        map20.put("name_chn", "对象ID");
        map20.put("name_eng", "dev_id");
        Map<String, Object> map21 = new HashMap<>();
        map21.put("name_chn", "对象名称");
        map21.put("name_eng", "dev_name");
        Map<String, Object> map22 = new HashMap<>();
        map22.put("name_chn", "数据类型");
        map22.put("name_eng", "asset_name");
        Map<String, Object> map23 = new HashMap<>();
        map23.put("name_chn", "有效点数");
        map23.put("name_eng", "valid_num");
        Map<String, Object> map24 = new HashMap<>();
        map24.put("name_chn", "异常点数");
        map24.put("name_eng", "abnormal_num");
        Map<String, Object> map25 = new HashMap<>();
        map25.put("name_chn", "异常说明");
        map25.put("name_eng", "abnormal_content");
        Map<String, Object> map26 = new HashMap<>();
        map26.put("name_chn", "日期");
        map26.put("name_eng", "day_time");

        accuracyRateContentTwoLevel.add(map20);
        accuracyRateContentTwoLevel.add(map21);
        accuracyRateContentTwoLevel.add(map22);
        accuracyRateContentTwoLevel.add(map23);
        accuracyRateContentTwoLevel.add(map24);
        accuracyRateContentTwoLevel.add(map25);
        accuracyRateContentTwoLevel.add(map26);

        dynamicHeader.put("accuracyRateContent1003TwoLevel", accuracyRateContentTwoLevel);



    }
}
